package com.bj58.heatmap.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.bj58.dsap.api.scf.contract.IHbaseApi;
import com.bj58.dsap.api.scf.contract.Result;
import com.bj58.heatmap.main.WebCrawler;

/**
 * 老版PC热力图，直接根据url从HBase匹配数据
 * @author zhaoxiang
 *
 */
public class ChangeStyle {

	private static IHbaseApi hbase;
	private static String tablename = "ZhHomeHeatmapHBase";
	static {
		ScfUtil.initSCF();
		hbase = ScfUtil.getHbaseService();
	}
	private static String buttonBar = "";
	private static String colorBar = "\n<div align=\"center\">\n"
		+ "<table height=\"35\">\n" + "<tr>\n"
		+ "<td style=\"width:10%\" bgcolor=\"#e1e1e1\"></td>\n"+
		"<td><font color='red'><#1#</font></td>\n"+
		"<td style=\"width:10%\" bgcolor=\"#ffd985\"></td>\n"+
		"<td><font color='red'><#2#</font></td>\n"+
		"<td style=\"width:10%\" bgcolor=\"#ffa037\"></td>\n"+
		"<td><font color='red'><#3#</font></td>\n"+
		"<td style=\"width:10%\" bgcolor=\"#ff5f3d\"></td>\n"+
		"<td><font color='red'><#4#</font></td>\n"+
		 "<td style=\"width:10%\" bgcolor=\"#be0100\"></td>\n"
		+ "</tr>\n" + "</table>\n" + "</div>\n";
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Calendar calendar = Calendar.getInstance();
		String folder="";
		if(args==null||args.length==0){
			calendar.add(Calendar.DATE, -1);
			folder = new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
		}
		else{
			folder=args[0];
			calendar.set(Calendar.YEAR, Integer.parseInt(folder.substring(0, 4)));
			calendar.set(Calendar.MONTH, Integer.parseInt(folder.substring(4, 6))-1);
			calendar.set(Calendar.DATE, Integer.parseInt(folder.substring(6, 8)));
		}
		String lastday = DDateUtils.varDate(folder, "yyyyMMdd", Calendar.DATE, -1);
		File savePath = new File(WebCrawler.getHtmlPath() + folder);
		File savePath_new = new File(WebCrawler.getHtmlPath_new() + folder);
		if (!savePath_new.exists())
			savePath_new.mkdirs();
		File[] files = savePath.listFiles();
		for (File f : files) {
			if (f.isFile()) {
				String html = readFile(f);
				String t="pkg/index/index_common_homepage";
				html=html.replaceAll(t, "");
				String filename = f.getName();
				if (filename.endsWith("_M.html")) //只处理M端的
					continue;				
				html = changeStyle(html, folder,lastday,filename);
				saveFile(html, new File(savePath_new, filename));
			}
		}
		System.out.println("ChangeStyle complete!");
		System.exit(0);
	}

	/**
	 * 读文件
	 * 
	 * @param file
	 * @return
	 */
	public static String readFile(File file) {
		String line_separator = System.getProperty("line.separator");
		StringBuilder html = new StringBuilder();
		try {
			BufferedReader br = new BufferedReader(new FileReader(file));
			String line = null;
			while ((line = br.readLine()) != null) {
				html.append(line);
				html.append(line_separator);
			}
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
			return html.toString();
		}
		return html.toString();
	}

	/**
	 * 写文件
	 * 
	 * @param content
	 * @param file
	 */
	public static void saveFile(String content, File file) {
		try {
			BufferedWriter bw = new BufferedWriter(new FileWriter(file));
			bw.write(content);
			bw.flush();
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
	}

	/**
	 * 更改静态页面
	 * @param html
	 * @return
	 */
	public static String changeStyle(String html, String date,String lastday, String filename) {
		String city=null;
		String rowkey_prefix = null;
		if (filename.endsWith("_M.html")) {
			city = filename.substring(0, filename.lastIndexOf("_"));
			//从hbase读数据
			rowkey_prefix = date + "_M_" + city + "_";
			Map<String, String> pv_uv_result = getDataByPrefix(tablename,rowkey_prefix);
			rowkey_prefix = lastday + "_M_" + city + "_";
			Map<String, String> pv_uv_result_Y = getDataByPrefix(tablename,rowkey_prefix);
			//平均值
			long avgPV = getAVG(html, pv_uv_result);
			//切点
			long[] cutPoints = getCutPoint(avgPV);
			//根据链接匹配数据
			html = change_M(pv_uv_result,pv_uv_result_Y,date,html,cutPoints);
			//添加颜色区间bar
			html = addColorBar_M(date, city, html, cutPoints);
		} else {
			city = filename.substring(0, filename.lastIndexOf("."));
			//从hbase读数据
			rowkey_prefix = date + "_PC_" + city + "_";
			Map<String, String> pv_uv_result = getDataByPrefix(tablename,rowkey_prefix);
			rowkey_prefix = lastday + "_PC_" + city + "_";
			Map<String, String> pv_uv_result_Y = getDataByPrefix(tablename,rowkey_prefix);
			//平均值
			long avgPV = getAVG(html, pv_uv_result);
			//切点
			long[] cutPoints = getCutPoint(avgPV);
			//根据链接匹配数据
			html = change_PC(pv_uv_result,pv_uv_result_Y,date,html,cutPoints);
			//添加颜色区间bar
			html = addColorBar_PC(date, city, html, cutPoints);
		}
		return html;
	}

	/**
	 * 添加颜色区间bar
	 * @param date
	 * @param city
	 * @param html
	 * @param maxUV
	 * @return
	 */
	public static String addColorBar_PC(String date,String city,String html,long[] cutPoints){
		//添加label，指向该城市M端的链接
		buttonBar = "<div align=\"center\">\n<br/>\n<button type=\"button\">\n"
			+ " <a href=\"/heatmap/getPage?selectpvtype=m&selectdate="+date+"&selectedcityname="+city+"\" target=\"_self\">切换到m端</a>\n" + "</button>\n</div>";
		String replacedColorBar = colorBar.replace("#1#", String.valueOf(cutPoints[0]));
		replacedColorBar = replacedColorBar.replace("#2#", String.valueOf(cutPoints[1]));
		replacedColorBar = replacedColorBar.replace("#3#", String.valueOf(cutPoints[2]));
		replacedColorBar = replacedColorBar.replace("#4#", String.valueOf(cutPoints[3]));
		html=html.replaceFirst("<div\\s{1,}(.*?)id=('|\")header\\2(.*?)>", "<div $1id=\"header\"$3>" + replacedColorBar+buttonBar);
		return html;
	}
	
	public static String addColorBar_M(String date,String city,String html,long[] cutPoints){
		//添加button，指向该城市 PC 端的链接
		buttonBar = "<div align=\"center\">\n<br/>\n<button type=\"button\">\n"
			+ " <a href=\"/heatmap/getPage?selectpvtype=pc&selectdate="+date+"&selectedcityname="+city+"\" target=\"_self\">切换到pc端</a>\n" + "</button>\n</div>";
		String replacedColorBar = colorBar.replace("#1#", String.valueOf(cutPoints[0]));
		replacedColorBar = replacedColorBar.replace("#2#", String.valueOf(cutPoints[1]));
		replacedColorBar = replacedColorBar.replace("#3#", String.valueOf(cutPoints[2]));
		replacedColorBar = replacedColorBar.replace("#4#", String.valueOf(cutPoints[3]));
		html=html.replaceFirst("(<body.*?>)","$1" + replacedColorBar+buttonBar);
		return html;
	}
	
	public static String change_PC(Map<String, String> pv_uv_result,Map<String, String> pv_uv_result_Y, String date, String html,long[] cutPoints){
		StringBuffer sb = new StringBuffer();
		try {
			Pattern p = Pattern.compile("<a(.*?)\\s*>", Pattern.DOTALL);
			Pattern href = Pattern.compile("href=(['\"])(.*?)\\1");
			Matcher m = p.matcher(html);
			while (m.find()) {
				String a = m.group(1);
				Matcher mat = href.matcher(a);
				if (!mat.find()) {
					String x= m.group(0);
					m.appendReplacement(sb, x);
					continue;
				}
				String toURL = mat.group(2).trim();
				String pv_uv_data = pv_uv_result.get(toURL.trim());
				String pv_uv_data_Y=pv_uv_result_Y.get(toURL.trim());
				int pvCount = 0, uvCount = 0,lastpv=0,lastuv=0;
				if (pv_uv_data != null) {
					String[] tmp = pv_uv_data.split("_");
					pvCount = Integer.parseInt(tmp[0]);
					uvCount = Integer.parseInt(tmp[1]);
				}
				if(pv_uv_data_Y!=null){
					String[] tmp = pv_uv_data_Y.split("_");
					lastpv = Integer.parseInt(tmp[0]);
					lastuv = Integer.parseInt(tmp[1]);
				}
				if (pvCount < cutPoints[0])
					m.appendReplacement(sb,changeColor(a, "#e1e1e1", pvCount, uvCount,lastpv,lastuv));
				else if (pvCount < cutPoints[1])
					m.appendReplacement(sb,
							changeColor(a, "#ffd985", pvCount, uvCount,lastpv,lastuv));
				else if (pvCount < cutPoints[2])
					m.appendReplacement(sb,
							changeColor(a, "#ffa037", pvCount, uvCount,lastpv,lastuv));
				else if (pvCount < cutPoints[3])
					m.appendReplacement(sb,
							changeColor(a, "#ff5f3d", pvCount, uvCount,lastpv,lastuv));
				else
					m.appendReplacement(sb,
							changeColor(a, "#be0100", pvCount, uvCount,lastpv,lastuv));
			}
			m.appendTail(sb);
		} catch (Exception e) {
			e.printStackTrace();
			return html;
		}
		return changeImgPath(sb.toString(),date);
	}
	
	public static String change_M(Map<String, String> pv_uv_result, Map<String, String> pv_uv_result_Y,String date, String html,long[] cutPoints){
		StringBuffer sb = new StringBuffer();
		try {
			Pattern p = Pattern.compile("<a(.*?)\\s*>", Pattern.DOTALL);
			Pattern href = Pattern.compile("href=(['\"])(.*?)\\1");
			Matcher m = p.matcher(html);
			while (m.find()) {
				String a = m.group(1);
				Matcher mat = href.matcher(a);
				if (!mat.find()) {
					String x= m.group(0);
					m.appendReplacement(sb, x);
					continue;
				}
				String toURL = mat.group(2).trim();
				String pv_uv_data = pv_uv_result.get(toURL.trim());
				String pv_uv_data_Y=pv_uv_result_Y.get(toURL.trim());
				int pvCount = 0, uvCount = 0,lastpv=0,lastuv=0;
				if (pv_uv_data != null) {
					String[] tmp = pv_uv_data.split("_");
					pvCount = Integer.parseInt(tmp[0]);
					uvCount = Integer.parseInt(tmp[1]);
				}
				if(pv_uv_data_Y!=null){
					String[] tmp = pv_uv_data_Y.split("_");
					lastpv = Integer.parseInt(tmp[0]);
					lastuv = Integer.parseInt(tmp[1]);
				}
				if (pvCount < cutPoints[0])
					m.appendReplacement(sb,changeColor(a, "#e1e1e1", pvCount, uvCount,lastpv,lastuv));
				else if (pvCount < cutPoints[1])
					m.appendReplacement(sb,
							changeColor(a, "#ffd985", pvCount, uvCount,lastpv,lastuv));
				else if (pvCount < cutPoints[2])
					m.appendReplacement(sb,
							changeColor(a, "#ffa037", pvCount, uvCount,lastpv,lastuv));
				else if (pvCount < cutPoints[3])
					m.appendReplacement(sb,
							changeColor(a, "#ff5f3d", pvCount, uvCount,lastpv,lastuv));
				else
					m.appendReplacement(sb,
							changeColor(a, "#be0100", pvCount, uvCount,lastpv,lastuv));
			}
			m.appendTail(sb);
		} catch (Exception e) {
			e.printStackTrace();
			return html;
		}
		return changeImgPath_M(sb.toString(),date);
	}
	
	/**
	 * 更改背景色
	 * 
	 * @param a
	 * @param color
	 * @param pv
	 * @param uv
	 * @return
	 */
	public static String changeColor(String a, String color, int pv, int uv,int lastpv,int lastuv) {
		String startStr = "<a title=\"点击量:" + pv + "&#13;点击人数:" + uv + "&#13;前一天：&#13;点击量:"+ lastpv + "&#13;点击人数:" + lastuv + "\"";
		String replaced;
		int i = a.indexOf("style=\"");
		if (i > 0) {
			replaced = startStr + a.substring(0, i)
					+ "style=\"background-color:" + color + "; "
					+ a.substring(i + 7) + ">";
		} else
			replaced = startStr + a + " style=\"background-color:" + color
					+ "\">";
		// System.out.println(replaced);
		return replaced;
	}

	/**
	 * 更改图片路径
	 * 
	 * @param html
	 * @param date
	 * @return
	 */
	public static String changeImgPath(String html, String date) {
		StringBuffer sb = new StringBuffer();
		ArrayList<String> srcList = new ArrayList<String>();
		String srcReg = "http://([^<>'+()]*?)\\.(js|css|jpeg|jpg|png|gif|bmp|swf)";
		try {
			Pattern p = Pattern.compile(srcReg);
			Matcher m = p.matcher(html);
			while (m.find()) {
				String src = m.group();
				srcList.add(src);
				int i = src.indexOf("?");
				if (i != -1)
					src = src.substring(0, i);
				m.appendReplacement(sb,
						"/heatmap/" + date + "/"
								+ src.substring(src.lastIndexOf("/") + 1));
			}
			m.appendTail(sb);
		} catch (Exception e) {
			e.printStackTrace();
			return html;
		}
		return sb.toString();
	}

	/**
	 * 更改图片路径
	 * 
	 * @param html
	 * @param date
	 * @return
	 */
	public static String changeImgPath_M(String html, String date) {
		StringBuffer sb = new StringBuffer();
		ArrayList<String> srcList = new ArrayList<String>();
		String srcReg = "http://([^<>'+()]*?)\\.(js|css|jpeg|jpg|png|gif|bmp|swf)";
		try {
			Pattern p = Pattern.compile(srcReg);
			Matcher m = p.matcher(html);
			while (m.find()) {
				String src = m.group();
				srcList.add(src);
				int i = src.indexOf("?");
				if (i != -1)
					src = src.substring(0, i);
				m.appendReplacement(sb,
						"/heatmap/" + date + "/M_"
								+ src.substring(src.lastIndexOf("/") + 1));
			}
			m.appendTail(sb);
		} catch (Exception e) {
			e.printStackTrace();
			return html;
		}
		return sb.toString();
	}
	
	/**
	 * 根据前缀从HBase查PV，UV
	 * 
	 * @param tableName
	 * @param prefix
	 * @return
	 */
	public static Map<String, String> getDataByPrefix(String tableName,
			String prefix) {
		Map<String, String> key_value = new HashMap<String, String>();
		try {
			List<Result> resList = hbase.nextPagesByKeyPrefix(
					"ZhHomeHeatmapHBase", prefix, "", 1000);
			while (resList.size() >= 1000) {
				for (Result result : resList) {
					Map<String, Object> scfMap = result.getScfMap();
					String rowkey = (String) scfMap.get("rowKey");
					String value = "";
					String PV = (String) scfMap.get("cf:pv");
					String UV = (String) scfMap.get("cf:uv");
					value = PV + "_" + UV;
					key_value.put(rowkey.substring(prefix.length()), value);
				}
				String lastRowkey = (String) resList.get(999).getScfMap()
						.get("rowKey");
				resList = hbase.nextPagesByKeyPrefix("ZhHomeHeatmapHBase",
						prefix, lastRowkey, 1000);
			}
			for (Result result : resList) {
				Map<String, Object> scfMap = result.getScfMap();
				String rowkey = (String) scfMap.get("rowKey");
				String value = "";
				String PV = (String) scfMap.get("cf:pv");
				String UV = (String) scfMap.get("cf:uv");
				value = PV + "_" + UV;
				key_value.put(rowkey.substring(prefix.length()), value);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return key_value;
		}
		return key_value;
	}
	
	public static long getAVG(String html, Map<String, String> pv_uv_result){
		Pattern p = Pattern.compile("<a(.*?)\\s*>", Pattern.DOTALL);
		Pattern href = Pattern.compile("href=(['\"])(.*?)\\1");
		Matcher m = p.matcher(html);
		long totalPV = 0;
		int linkCount = 0;
		while (m.find()) {
			String a = m.group(1);
			Matcher mat = href.matcher(a);
			if (!mat.find()) {
				continue;
			}
			
			String toURL = mat.group(2).trim();
			String pv_uv_data = pv_uv_result.get(toURL.trim());
			if (pv_uv_data != null) {
				String[] tmp = pv_uv_data.split("_");
				long pvCount = Long.parseLong(tmp[0]);
				totalPV += pvCount;
				linkCount++;	//链接数
			}
		}
		if(linkCount !=0)
			return totalPV/linkCount;
		return 1;
	}
	
	public static long[] getCutPoint(long avg){
		long p1 = (long)(avg*0.6);
		long p2 = (long)(avg*1.8);
		long p3 = (long)(avg*3);
		long p4 = (long)(avg*6);
		if(avg >= 167){
			return new long[]{p1/100*100,p2/100*100,p3/100*100,p4/100*100};
		}else if(avg <=17){
			return new long[]{p1,p2,p3,p4};
		}else{
			return new long[]{p1/10*10,p2/10*10,p3/10*10,p4/10*10};
		}
	}
}
